import os
from concurrent.futures import ThreadPoolExecutor

import tornado.ioloop
import tornado.web
import tornado.httpserver
import logging

from tornado import gen
from tornado.concurrent import run_on_executor
from tornado.httpclient import HTTPError
from controller_example import ControllerExample

from tornado.options import options, define

import json
import abc

# 这里配置的是日志的路径，配置好后控制台的相应信息就会保存到目标路径中。
options.log_file_prefix = os.path.join(os.path.dirname(__file__), 'logs/tornado_main.log')

NUMBER_OF_EXECUTOR = 6


class BasePostRequestHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(NUMBER_OF_EXECUTOR)

    @gen.coroutine
    def post(self, *args, **kwargs):
        try:
            result = yield self._post(*args, **kwargs)
            self.write(result)
        except HTTPError as e:
            self.write(e)
        except Exception as e:
            logging.error(e)
            raise HTTPError(404, "No results")

    @run_on_executor
    def _post(self, *args, **kwargs):
        request = self._post_request_arguments(*args, **kwargs)
        res = self._request_service(**request)
        return res

    @abc.abstractmethod
    def _post_request_arguments(self, *args, **kwargs):
        raise NotImplementedError('call to abstract method %s._get_request_arguments' % self.__class__)

    @abc.abstractmethod
    def _request_service(self, **kwargs):
        raise NotImplementedError('call to abstract method %s._request_service' % self.__class__)


class ChangeModel(BasePostRequestHandler):
    def _post_request_arguments(self, *args, **kwargs):
        data = json.loads(self.request.body)
        if not data:
            raise HTTPError(400, "Query argument cannot be empty string")
        return data

    def _request_service(self, **kwargs):
        if kwargs:
            c_e = ControllerExample(kwargs)
            res = c_e.do_add()
        else:
            raise HTTPError(400, "Query argument cannot be empty string")
        return res


# 格式化日志输出格式
# 默认是这种的：[I 160807 09:27:17 web:1971] 200 GET / (::1) 7.00ms
# 格式化成这种的：[2016-08-07 09:38:01 执行文件名:执行函数名:执行行数 日志等级] 内容消息
class LogFormatter(tornado.log.LogFormatter):
    def __init__(self):
        super(LogFormatter, self).__init__(
            fmt='%(color)s[%(asctime)s %(filename)s:%(funcName)s:%(lineno)d %(levelname)s]%(end_color)s %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )


def Application():
    return tornado.web.Application([
        # 请求的路由地址配置
        (r"/object_detection", ChangeModel),
    ], debug=True)


def main():
    tornado.options.define("port", default="9872", help="run on the port", type=int)  # 设置全局变量port
    tornado.options.parse_command_line()  # 启动应用前面的设置项目
    [i.setFormatter(LogFormatter()) for i in logging.getLogger().handlers]
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(tornado.options.options.port)  # 在这里应用之前的全局变量port
    tornado.ioloop.IOLoop.current().start()  # 启动监听


if __name__ == "__main__":

    main()
# if __name__ == "__main__":
#     app = make_app()
#     sockets = tornado.netutil.bind_sockets(10031)
#     http_server = tornado.httpserver.HTTPServer(app)
#     http_server.add_sockets(sockets)
#     print("Server Start Ok.....")
#     tornado.ioloop.IOLoop.instance().start()
